home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xmris / demo.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  14KB  |  560 lines

  1. /*{{{  (C) 1992 Nathan Sidwell*/
  2. /*****************************************************************************
  3.             X M R I S V1.01
  4.             ---------------
  5.             (C) 1992 Nathan Sidwell
  6.  
  7. This program is copyright (C) 1992 Nathan Sidwell. This software and documentation
  8. is in the public domain. Permission is granted to distribute and compile
  9. verbatim copies of this software for non-commercial, non-profit use,
  10. without fee. The software may be modified, provided that both the above copyright
  11. notice and this permission notice appear.
  12.  
  13. No guarantee is given as to the robustness or suitability of this
  14. software for your computer.
  15.  
  16. Nathan Sidwell  INMOS UK |                 | nathan@inmos.co.uk       DoD#0390
  17. *****************************************************************************/
  18. /*}}}*/
  19. #include "xmris.h"
  20. /*{{{  prototypes*/
  21. static int demo_board PROTOARGLIST((void));
  22. static int demo_keys PROTOARGLIST((void));
  23. static int move_demo PROTOARGLIST((void));
  24. static void move_mris PROTOARGLIST((void));
  25. /*}}}*/
  26. /*{{{  int demo_board()*/
  27. static int demo_board FUNCARGVOID
  28. {
  29.   unsigned  den;
  30.   unsigned  count;
  31.   unsigned  quit;
  32.  
  33.   quit = 0;
  34.   player.screen = random() % 10;
  35.   extra.select = random() % 5;
  36.   extra.got = random() & 0x1F;
  37.   create_xtra_monster(extra.select);
  38.   new_board();
  39.   zoom_board();
  40.   draw_center(SPRITE_DEN);
  41.   monster.monsters = 0;
  42.   spawn_monster(4, 2, 2, PLAYER_START_X, PLAYER_START_Y, 0, 0);
  43.   monster.list[0].stop = 1;
  44.   monster.den = 0;
  45.   player.ball.state = 0;
  46.   player.ball.count = 8;
  47.   player.old_ball.state = 0;
  48.   /*{{{  plonk on M R I S*/
  49.   for(count = 4; count--;)
  50.     {
  51.       unsigned  x, y;
  52.       unsigned  j;
  53.       CELL      *cptr;
  54.       
  55.       do
  56.     {
  57.       do
  58.         j = random();
  59.       while(j >= CELLS_ACROSS * CELLS_DOWN);
  60.       x = j % CELLS_ACROSS;
  61.       y = j / CELLS_ACROSS;
  62.       cptr = BOARDCELL(x, y);
  63.     }
  64.       while(!cptr->visit);
  65.       spawn_monster(SPRITE_MRIS + count + (random() & 4), 0, 0, x, y, 0, 0);
  66.     }
  67.   /*}}}*/
  68.   refresh_window();
  69.   count = DISPLAY_HOLD;
  70.   den = 4;
  71.   timer_start(FRAME_RATE);
  72.   while(count)
  73.     {
  74.       quit = process_xevents(0);
  75.       if(quit)
  76.     {
  77.       player.button = 1;
  78.       break;
  79.     }
  80.       /*{{{  calc distances?*/
  81.       if(den != monster.den)
  82.     {
  83.       den = monster.den;
  84.       monster.list[0].cell.y = 0;
  85.       monster.list[0].cell.x = 4 + den;
  86.       calc_distances();
  87.       monster.list[0].cell.y = PLAYER_START_Y;
  88.       monster.list[0].cell.x = PLAYER_START_X;
  89.     }
  90.       /*}}}*/
  91.       move_mris();
  92.       if(monster.den == 4)
  93.     count--;
  94.       if(player.button)
  95.     count = 0;
  96.       show_updates();
  97.     timer_wait();
  98.       }
  99.   timer_stop();
  100.   return quit;
  101. }
  102. /*}}}*/
  103. /*{{{  int demo_keys()*/
  104. static int demo_keys FUNCARGVOID
  105. {
  106.   unsigned  quit;
  107.   unsigned  count;
  108.  
  109.   monster.monsters = 0;
  110.   apple.apples = 0;
  111.   player.ball.state = 0;
  112.   player.ball.count = 8;
  113.   XFillRectangle(display.display, display.back, GCN(GC_CLEAR),
  114.       0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  115.   /*{{{  put on M R I S*/
  116.   {
  117.     unsigned  missing;
  118.     unsigned  index;
  119.     int       x, y;
  120.       
  121.     missing = random() & 3;
  122.     for(index = 4; index--;)
  123.       {
  124.     SPRITE    *sptr;
  125.       
  126.     sptr = &sprites[SPRITE_MRIS + index + 4 * (index == missing)];
  127.     XCopyArea(display.display, sptr->mask, display.back, GCN(GC_MASK),
  128.         0, 0, CELL_WIDTH, CELL_HEIGHT,
  129.         PIXELX(4 + index, 0), PIXELY(-1, 0));
  130.     XCopyArea(display.display, sptr->image, display.back, GCN(GC_OR),
  131.         0, 0, CELL_WIDTH, CELL_HEIGHT,
  132.         PIXELX(4 + index, 0), PIXELY(-1, 0));
  133.       }
  134.     y = random() % (CELLS_DOWN + 2) * (CELL_HEIGHT + GAP_HEIGHT);
  135.     x = random() & 1 ? CELLS_ACROSS * (CELL_WIDTH + GAP_WIDTH) :
  136.     -CELLS_ACROSS * (CELL_WIDTH + GAP_WIDTH);
  137.     spawn_monster(SPRITE_MRIS + missing, 0, 0, 4 + missing, -1, x, y);
  138.   }
  139.   /*}}}*/
  140.   XCopyArea(display.display, display.back, display.copy, GCN(GC_COPY),
  141.       0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
  142.   /*{{{  put on the title text*/
  143.   {
  144.     char const **tptr;
  145.     unsigned  length;
  146.     unsigned  index;
  147.     unsigned  gnome;
  148.       
  149.     gnome = 0;
  150.     for(tptr = title_text, index = 0; *tptr; tptr++, index++)
  151.       {
  152.     length = strlen(*tptr);
  153.     if(length)
  154.       {
  155.         TEXT      info;
  156.         char  const *ptr;
  157.         unsigned  shift;
  158.           
  159.         ptr = strchr(*tptr, '-');
  160.         if(ptr)
  161.           {
  162.         text_size(*tptr, ptr - *tptr + 1, &info);
  163.         shift = info.width;
  164.           }
  165.         else
  166.           shift = 0;
  167.         text_size(*tptr, length, &info);
  168.         XDrawImageString(display.display, display.back, GCN(GC_TEXT),
  169.         WINDOW_WIDTH / 2 - (shift ? shift : info.width / 2),
  170.         PIXELY(index, CELL_HEIGHT / 2) +
  171.         (info.ascent - info.descent) / 2, *tptr, length);
  172.         /*{{{  spawn monster*/
  173.         {
  174.           unsigned  type;
  175.           int       cellx;
  176.           int       offsetx;
  177.                 
  178.           do
  179.         {
  180.           type = random() & 3;
  181.           if(type & 2)
  182.             type++;
  183.         }
  184.           while(type == 4 && gnome);
  185.           if(type == 4)
  186.         gnome = 1;
  187.           if(random() & 1)
  188.         {
  189.           cellx = -2;
  190.           offsetx = (CELLS_ACROSS + 2) * (CELL_WIDTH + GAP_WIDTH);
  191.         }
  192.           else
  193.         {
  194.           cellx = CELLS_ACROSS + 1;
  195.           offsetx = -(CELLS_ACROSS + 5) * (CELL_WIDTH + GAP_WIDTH);
  196.         }
  197.           offsetx += CELL_WIDTH * (random() & 3);
  198.           spawn_monster(type, 0, 0, cellx, index, offsetx, 0);
  199.         }
  200.         /*}}}*/
  201.       }
  202.       }
  203.   }
  204.   /*}}}*/
  205.   count = DISPLAY_HOLD;
  206.   refresh_window();
  207.   timer_start(FRAME_RATE);
  208.   while(count)
  209.     {
  210.       quit = process_xevents(0);
  211.       if(quit)
  212.     {
  213.       player.button = 1;
  214.       break;
  215.     }
  216.       if(!move_demo())
  217.     count--;
  218.       if(player.button)
  219.     count = 0;
  220.       show_updates();
  221.       timer_wait();
  222.       }
  223.   timer_stop();
  224.   return quit;
  225. }
  226. /*}}}*/
  227. /*{{{  int demo_mode()*/
  228. extern int demo_mode FUNCARGVOID
  229. {
  230.   unsigned  quit;
  231.  
  232.   global.state = 6;
  233.   player.keyboard = 0;
  234.   player.button = 0;
  235.   player.pressed = 0;
  236.   player.old_ball.state = 0;
  237.   quit = 0;
  238.   while(!player.button)
  239.     {
  240.       if(!player.button)
  241.     quit = demo_keys();
  242.       if(!player.button)
  243.     quit = demo_board();
  244.     }
  245.   player.button = 0;
  246.   return quit;
  247. }
  248. /*}}}*/
  249. /*{{{  void extra_life()*/
  250. extern void extra_life FUNCARGVOID
  251. /* does the extra life senario */
  252. {
  253.   static char const *text[] = {"Congratulations", "You win extra", NULL};
  254.   unsigned  thrown;
  255.   
  256.   add_background(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  257.   XFillRectangle(display.display, display.back, GCN(GC_CLEAR),
  258.       BORDER_LEFT + 1, BORDER_TOP + 1, BOARD_WIDTH - 2, BOARD_HEIGHT - 2);
  259.   /*{{{  display some text*/
  260.   {
  261.     unsigned  line;
  262.     TEXT      info;
  263.     char const **tptr;
  264.     unsigned  length;
  265.       
  266.     line = BORDER_TOP + CELL_HEIGHT;
  267.     for(tptr = text; *tptr; tptr++)
  268.       {
  269.     length = strlen(*tptr);
  270.     text_size(*tptr, length, &info);
  271.     XDrawImageString(display.display, display.back, GCN(GC_TEXT),
  272.         WINDOW_WIDTH / 2 - info.width / 2,
  273.         line + info.ascent, *tptr, length);
  274.     line += info.ascent + info.descent;
  275.       }
  276.   }
  277.   /*}}}*/
  278.   monster.monsters = 0;
  279.   apple.apples = 0;
  280.   spawn_monster(4, 3, 3, 3, DEN_Y, -(CELL_WIDTH + GAP_WIDTH) * 3, 0);
  281.   spawn_monster(0, 2, 2, 0, DEN_Y,
  282.       (CELLS_ACROSS - 1) * (CELL_WIDTH + GAP_WIDTH), 0);
  283.   /*{{{  add m r i s*/
  284.   {
  285.     unsigned  i;
  286.     for(i = 4; i--;)
  287.       {
  288.     XCopyArea(display.display, sprites[SPRITE_MRIS + 4 + i].mask,
  289.         display.back, GCN(GC_MASK), 0, 0, CELL_WIDTH, CELL_HEIGHT,
  290.         PIXELX(CELLS_ACROSS / 2 - 2 + i, 0), PIXELY(2, 0));
  291.     XCopyArea(display.display, sprites[SPRITE_MRIS + 4 + i].image,
  292.         display.back, GCN(GC_OR), 0, 0, CELL_WIDTH, CELL_HEIGHT,
  293.         PIXELX(CELLS_ACROSS / 2 - 2 + i, 0), PIXELY(2, 0));
  294.     spawn_monster(SPRITE_MRIS + i, 1, 1, CELLS_ACROSS / 2 - 2 + i,
  295.         2, 0, -(CELL_HEIGHT + GAP_HEIGHT) * 3 - CELL_HEIGHT / 2 * i);
  296.       }
  297.   }
  298.   /*}}}*/
  299.   draw_extra_letter(extra.select);
  300.   player.pressed = 0;
  301.   /*{{{  create a path*/
  302.   {
  303.     unsigned  i;
  304.     CELL      *cptr;
  305.     
  306.     apple.apples = 0;
  307.     for(cptr = BOARDCELL(0, DEN_Y), i = CELLS_ACROSS; i--; cptr++)
  308.       {
  309.     cptr->visit = 1;
  310.     cptr->sprite = 0;
  311.     cptr->distance = CELLS_ACROSS - i;
  312.     cptr->depths[0] = 0;
  313.     cptr->depths[1] = 0;
  314.     cptr->depths[2] = -(CELL_WIDTH + GAP_WIDTH);
  315.     cptr->depths[3] = CELL_WIDTH + GAP_WIDTH;
  316.       }
  317.     BOARDCELL(0, DEN_Y)->depths[2] = 0;
  318.     BOARDCELL(CELLS_ACROSS - 1, DEN_Y)->depths[3] = 0;
  319.   }
  320.   /*}}}*/
  321.   global.state = 5;
  322.   thrown = 0;
  323.   while(thrown != 3)
  324.     {
  325.       process_xevents(1);
  326.       if(!monster.list[0].offset.x && !thrown)
  327.     {
  328.       thrown = 1;
  329.       player.throw = 1;
  330.     }
  331.       bounce_ball();
  332.       if(player.ball.state == 3)
  333.     player.ball.state = 4;
  334.       else if(player.ball.state == 4)
  335.     {
  336.       player.ball.pixel.x = PIXELX(player.lives - 1, 0) + CELL_WIDTH / 2;
  337.       player.ball.pixel.y = BORDER_TOP + BOARD_HEIGHT + 1 +
  338.           CELL_HEIGHT / 2 - (CELL_HEIGHT + GAP_HEIGHT) * 3;
  339.     }
  340.       else if(!player.ball.state && thrown == 1)
  341.     {
  342.       spawn_monster(SPRITE_PLAYER + 6, 0, 1, player.lives - 1, CELLS_DOWN,
  343.           0, -(CELL_HEIGHT + GAP_HEIGHT) * 3);
  344.       thrown = 2;
  345.     }
  346.       if(!move_demo() && thrown == 2)
  347.     thrown = 3;
  348.       show_updates();
  349.       timer_wait();
  350.     }
  351.   XCopyArea(display.display, display.copy, display.back, GCN(GC_COPY),
  352.       PIXELX(player.lives - 1, 0), PIXELY(CELLS_DOWN, 0),
  353.       CELL_WIDTH, CELL_HEIGHT,
  354.       PIXELX(player.lives - 1, 0), PIXELY(CELLS_DOWN, 0));
  355.   player.lives++;
  356.   return;
  357. }
  358. /*}}}*/
  359. /*{{{  int move_demo()*/
  360. static int move_demo FUNCARGVOID
  361. /*
  362.  * moves the monsters used in the demo screens
  363.  * we take each monster with a non-zero offset, and move it
  364.  * towards a zero offset (changing x first)
  365.  * it might get blown up by the ball
  366.  * returns the number of objects which moved
  367.  */
  368. {
  369.   MONSTER   *mptr;
  370.   unsigned  i;
  371.   unsigned  moved;
  372.  
  373.   moved = 0;
  374.   for(mptr = monster.list, i = monster.monsters; i--; mptr++)
  375.     {
  376.       if(mptr->shot)
  377.     mptr->type = 5;
  378.       else
  379.     {
  380.       if(mptr->offset.x)
  381.         /*{{{  left or right*/
  382.         {
  383.           int       dir;
  384.                 
  385.           moved++;
  386.           if(mptr->offset.x > 0)
  387.         {
  388.           dir = 2;
  389.           mptr->offset.x -= VEL_X;
  390.           mptr->pixel.x -= VEL_X;
  391.         }
  392.           else
  393.         {
  394.           dir = 3;
  395.           mptr->offset.x += VEL_X;
  396.           mptr->pixel.x += VEL_X;
  397.         }
  398.           if(dir != mptr->dir)
  399.         {
  400.           mptr->dir = dir;
  401.           new_face(mptr);
  402.         }
  403.                   
  404.         }
  405.         /*}}}*/
  406.       else if(mptr->offset.y)
  407.         /*{{{  up or down*/
  408.         {
  409.           int       dir;
  410.                 
  411.           moved++;
  412.           if(mptr->offset.y > 0)
  413.         {
  414.           dir = 0;
  415.           mptr->offset.y -= VEL_Y;
  416.           mptr->pixel.y -= VEL_Y;
  417.         }
  418.           else
  419.         {
  420.           dir = 1;
  421.           mptr->offset.y += VEL_Y;
  422.           mptr->pixel.y += VEL_Y;
  423.         }
  424.           if(dir != mptr->dir)
  425.         {
  426.           mptr->dir = dir;
  427.           new_face(mptr);
  428.         }
  429.                   
  430.         }
  431.         /*}}}*/
  432.       else
  433.         mptr->stop = 1;
  434.       if(!mptr->stop)
  435.         {
  436.           if(!mptr->cycle)
  437.         {
  438.           mptr->cycle = MONSTER_CYCLES;
  439.           mptr->image++;
  440.           if(mptr->image == MONSTER_IMAGES)
  441.             mptr->image = 0;
  442.         }
  443.           mptr->cycle--;
  444.         }
  445.     }
  446.     
  447.     }
  448.   return moved;
  449. }
  450. /*}}}*/
  451. /*{{{  void move_mris()*/
  452. static void move_mris FUNCARGVOID
  453. /*
  454.  * moves M R I S sprites around the board
  455.  * towards the top
  456.  */
  457. {
  458.   unsigned  i;
  459.   MONSTER   *mptr;
  460.  
  461.   for(mptr = &monster.list[1], i = monster.monsters - 1; i--; mptr++)
  462.     {
  463.       CELL      *cptr;
  464.     
  465.       assert(mptr->type >= SPRITE_MRIS && mptr->type < SPRITE_MRIS + 8);
  466.       cptr = BOARDCELL(mptr->cell.x, mptr->cell.y);
  467.       if(mptr->offset.x || mptr->offset.y)
  468.     move_movable(mptr, cptr);
  469.       else if(!mptr->cell.y && mptr->cell.x == 4 + i)
  470.     {
  471.       if(monster.den == i)
  472.         monster.den = i + 1;
  473.     }
  474.       else
  475.     {
  476.       unsigned  valid;
  477.       unsigned  temp;
  478.       
  479.       valid = valid_directions(mptr, cptr);
  480.       temp = valid & (0xF ^ (1 << (mptr->dir ^ 1)));
  481.       if(temp)
  482.         valid &= temp | 0xF0;
  483.       if(monster.den == i && (temp = valid & (valid >> 4)))
  484.         valid = temp;
  485.       else
  486.         valid &= 0xF;
  487.       mptr->dir = choose_direction(valid);
  488.       move_movable(mptr, cptr);
  489.     }
  490.     }
  491.   return;
  492. }
  493. /*}}}*/
  494. /*{{{  void show_history()*/
  495. extern void show_history FUNCARGVOID
  496. /* shows the history list */
  497. {
  498.   unsigned  count;
  499.   
  500.   add_background(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  501.   draw_extra_letter(extra.select);
  502.   XFillRectangle(display.display, display.back, GCN(GC_CLEAR),
  503.       BORDER_LEFT + 1, BORDER_TOP + 1, BOARD_WIDTH - 2, BOARD_HEIGHT - 2);
  504.   monster.monsters = 0;
  505.   apple.apples = 0;
  506.   player.ball.state = 0;
  507.   player.ball.count = 8;
  508.   player.old_ball.state = 0;
  509.   /*{{{  add in the parts*/
  510.   {
  511.     unsigned  base;
  512.     unsigned  screens;
  513.     unsigned  index;
  514.     TEXT      info;
  515.     char      text[11];
  516.     unsigned  length;
  517.     static int sprites[3] = {SPRITE_CHERRY, SPRITE_NORMAL + 4, SPRITE_PLAYER + 4};
  518.       
  519.     screens = player.screen < CELLS_DOWN - 2 ? player.screen : CELLS_DOWN - 2;
  520.     base = player.screen - screens;
  521.     text_size("Screen 090", 10, &info);
  522.     for(index = screens; index--;)
  523.       {
  524.     sprintf(text, "Screen %d", base + index + 1);
  525.     length = strlen(text);
  526.     XDrawImageString(display.display, display.back, GCN(GC_TEXT),
  527.         PIXELX(CELLS_ACROSS / 2, -GAP_WIDTH) - info.width,
  528.         PIXELY(screens - index, (CELL_HEIGHT + GAP_HEIGHT) / 2) +
  529.         (info.ascent - info.descent) / 2,
  530.         text, length);
  531.     if(history.prize & 1 << (screens - 1 - index))
  532.       spawn_monster(SPRITE_PRIZE_BASE +
  533.           (base + index) % SPRITE_PRIZES, 0, 0,
  534.           CELLS_ACROSS / 2 + 2, screens - index,
  535.           0, index * (2 * CELL_HEIGHT + GAP_HEIGHT) +
  536.           CELLS_DOWN * GAP_HEIGHT + CELL_HEIGHT / 2 + GAP_HEIGHT +
  537.           (CELL_HEIGHT + GAP_HEIGHT) * (2 + CELLS_DOWN - screens));
  538.     spawn_monster(sprites[(history.ending >>
  539.         (screens - 1 - index) * 2) & 3],
  540.         0, 0, CELLS_ACROSS / 2, screens - index,
  541.         0, index * (2 * CELL_HEIGHT + GAP_HEIGHT) +
  542.         CELLS_DOWN * GAP_HEIGHT + 
  543.         (CELL_HEIGHT + GAP_HEIGHT) * (2 + CELLS_DOWN - screens));
  544.       }
  545.   }
  546.   /*}}}*/
  547.   global.state = 8;
  548.   count = DISPLAY_HOLD;
  549.   while(count)
  550.     {
  551.       process_xevents(1);
  552.       if(!move_demo())
  553.     count--;
  554.       show_updates();
  555.       timer_wait();
  556.     }
  557.   return;
  558. }
  559. /*}}}*/
  560.